import type { ILlmSchema } from "@samchon/openapi";

import type { MicroAgenticaContext } from "../context/MicroAgenticaContext";
import type { AgenticaExecuteHistory } from "../histories/AgenticaExecuteHistory";

/**
 * Executor of the Micro Agentic AI.
 *
 * `IMicroAgenticaExecutor` represents an executor of the
 * {@link MicroAgentica}, composing its internal agents to accomplish
 * the Agentic AI through the LLM (Large Language Model) function
 * calling.
 *
 * You can customize one of these intnernal agents by configuring
 * properties of the `IMicroAgenticaExecutor` type, and assigning
 * it to the {@link IMicroAgenticaConfig.executor} property.
 *
 * @author Samchon
 */
export interface IMicroAgenticaExecutor<Model extends ILlmSchema.Model> {
  /**
   * Function caller agent.
   *
   * `Call` agent performs the LLM (Large Language Model) function
   * calling from the candidate functions enrolled in the
   * {@link AgenticaContext.stack}. And the scope of function calling
   * is, not only just arguments filling, but also actual executing
   * the function and returning the result.
   *
   * By the way, conversation context with user can be not enough to
   * filling the arguments of the candidate functions. In that case,
   * the `call` agent will ask the user to fill the missing arguments.
   *
   * Otherwise the cpnversation context is enough, so that succeeded
   * to call some candidate functions, the `call` agent will step to
   * the {@link describe} agent to explain the result of the function
   * calling to the user as markdown content.
   *
   * @param ctx Context of the agent
   * @returns List of prompts generated by the caller
   * @warning Recommend not to customize, due to its validation
   *          feedback strategy is working very well, and the `call`
   *          agent is the most general topic which can be universally
   *          applied to all domain fields.
   */
  call: (ctx: MicroAgenticaContext<Model>) => Promise<AgenticaExecuteHistory<Model>[]>;

  /**
   * Describer agent of the function calling result.
   *
   * `Describe` agent explains the results of the function callings
   * to the user as markdown content.
   *
   * If you configure this property as `false` or `null`, the describer
   * agent never be used.
   *
   * @param ctx Context of the agent
   * @param executes List of function calling results
   * @returns List of prompts generated by the describer
   */
  describe:
    | boolean
    | null
    | ((
      ctx: MicroAgenticaContext<Model>,
      executes: AgenticaExecuteHistory<Model>[],
    ) => Promise<void>);
}
